package view;

import java.util.GregorianCalendar;
import java.util.List;

import pojo.Aluno;
import pojo.Atividade;
import pojo.Disciplina;
import pojo.Professor;
import pojo.AlunoTurma;
import pojo.NotaAtividade;
import pojo.Turma;
import dao.AlunoDao;
import dao.AlunoDaoImp;
import dao.AlunoTurmaDao;
import dao.AtividadeDao;
import dao.AtividadeDaoImp;
import dao.DisciplinaDao;
import dao.DisciplinaDaoImp;
import dao.NotaAtividadeDao;
import dao.ProfessorDao;
import dao.ProfessorDaoImp;
import dao.NotaAtividadeDaoImp;
import dao.AlunoTurmaDaoImp;
import dao.TurmaDao;
import dao.TurmaDaoImp;


public class Menu {
	
	private ProfessorDao profDao;
	private AlunoDao alunoDao;
	private DisciplinaDao disciplinaDao;
	private TurmaDao turmaDao;
	private AtividadeDao atividadeDao;
	private NotaAtividadeDao notaAtividadeDao;
	private AlunoTurmaDao alunoTurmaDao;
	
	
	public Menu(){
		
		profDao = new ProfessorDaoImp();
		alunoDao = new AlunoDaoImp();
		disciplinaDao = new DisciplinaDaoImp();
		turmaDao = new TurmaDaoImp();
		atividadeDao = new AtividadeDaoImp();
		notaAtividadeDao = new NotaAtividadeDaoImp();
		alunoTurmaDao = new AlunoTurmaDaoImp();
		
	}
	public void show(){		
			
		while (true) {
			//clearScreen();
			System.out.println("=============================================================");
			System.out.println("Bem vindo ao sistema. Selecione sua categoria: ");
			System.out.println("1 - Professor");
			System.out.println("2 - Administrador");
			System.out.println("3 - Consultas");
			System.out.println("4 - Sair");
			int opcao = Console.readInteger();
			if (opcao == 1) {
				showProfessor();
			} else if (opcao == 2 ) {
				showAdm();
			} else if (opcao == 3 ) {
				consultas();
			} else if (opcao == 4 ) {
				break;
			} else if (opcao == -149 ) {
				if (clearAll()) {
					System.out.println("Apagado!");
					break;
				}
			} else {
				System.out.println("Opção invalida! Tente novamente");
				Console.readChar();
			}
		}
		System.out.print("Salvando...");
		profDao.saveData();
		System.out.print(".");
		alunoDao.saveData();
		System.out.print(".");
		disciplinaDao.saveData();
		System.out.print(".");
		turmaDao.saveData();
		System.out.print(".");
		atividadeDao.saveData();
		System.out.print(".");
		notaAtividadeDao.saveData();
		System.out.print(".");
		alunoTurmaDao.saveData();
		System.out.print(".");
		System.out.println("salvo");
	}
	private void consultas() {
		while (true) {
			//clearScreen();
			System.out.println("=============================================================");
			System.out.println("Qual consulta desejas fazer?");
			System.out.println("1 - Consultar Turmas por Disciplina, Ano e Periodo");
			System.out.println("2 - Consultar situação de um Aluno em uma Disciplina");
			System.out.println("3 - Consultar o numero de turmas já oferecidas de uma Disciplina");
			System.out.println("4 - Consultar o numero de Disciplinas já lecionads por um Professor");
			System.out.println("5 - Sair");
			
			int opcao = Console.readInteger();
			if (opcao == 1) {
				consultarTurmas();
			} else if (opcao == 2 ) {
				consultarSituacaoAluno();
			} else if (opcao == 3 ) {
				consultarTurmasDaDisciplina();
			} else if (opcao == 4 ) {
				consultarDisciplinasDeProfessor();
			} else if (opcao == 5 ) {
				return;
			} else {// TODO Auto-generated method stub
				System.out.println("Opcaoo invalida! Tente novamente");
			}
			Console.readChar();
		}
		
	}
	private void consultarTurmas() {
		Disciplina disciplina = selectDisciplina();
		if (disciplina == null) {
			System.out.println("Nenhuma Disciplina cadastrada.");
			return;
		}
		System.out.print("Digite o ano: ");
		int ano = Console.readInteger();
		System.out.print("Digite o periodo: ");
		int periodo = Console.readInteger();
		List<Turma> turmas = turmaDao.getByDisciplinaAnoPeriodo(disciplina.getId(), ano, periodo);
		if (turmas == null) {
			System.out.println("Não há uma turma desta disciplina neste ano e periodo.");
			return;
		}
		System.out.println("--------------------");
		for (Turma turma : turmas) {
			System.out.println("Turma do professor: " + profDao.get(turma.getProfessor()).getNome()
					+ " no horario: " + turma.getHorario());
			
			for (Integer id : turma.getListaRegistro()) {
				AlunoTurma at = alunoTurmaDao.get(id);
				at.atualizarNotaFinal(notaAtividadeDao);
				System.out.println(" -> Nome: " + alunoDao.get(at.getAlunoId()).getNome() +
									" Faltas: " + at.getFaltas() + " Nota Final: " + at.getNotaFinal(notaAtividadeDao));
			}
			System.out.println("--------------------");
		}
	}
	private void consultarSituacaoAluno() {
		Aluno aluno = selectAluno();
		if (aluno == null) {
			System.out.println("Nenhum aluno cadastrado.");
			return;
		}
		Disciplina disciplina = selectDisciplina(aluno);
		if (disciplina == null) {
			System.out.println("Nenhuma Disciplina cadastrada.");
			return;
		}
		List<AlunoTurma> lista = turmaDao.situacaoAluno(aluno.getTurmas(turmaDao, alunoTurmaDao), disciplina, aluno, alunoTurmaDao);
		System.out.println("--------------------");
		for (AlunoTurma alunoTurma : lista) {
			if ((alunoTurma.getNotaFinal(notaAtividadeDao) >= (float) 6.0) && 
				alunoTurma.getFaltas() <= (disciplina.getCargaHoraria()*0.25)) {
				System.out.println("Aluno " + aluno.getNome() + " foi aprovado " +
						"na disciplina " + disciplina.getNome() + " com nota: " +
						alunoTurma.getNotaFinal(notaAtividadeDao) + " e " + alunoTurma.getFaltas() +
						" faltas.");
			} else {
				System.out.println("Aluno " + aluno.getNome() + " não foi aprovado " +
						"na disciplina " + disciplina.getNome() + " com nota: " +
						alunoTurma.getNotaFinal(notaAtividadeDao) + " e " + alunoTurma.getFaltas() +
						" faltas.");
			}
		}
		System.out.println("--------------------");
	}
	private void consultarTurmasDaDisciplina() {
		System.out.println("=============================================================");
		System.out.println("Consulta de numero de Turmas já oferecidas de uma Disciplina");
		Disciplina disciplina = selectDisciplina();
		if (disciplina == null) {
			System.out.println("Nenhuma Disciplina cadastrada.");
			return;
		}
		int numeroTurmas = turmaDao.numeroOfertasPorDisciplina(disciplina.getId());
		System.out.println("Disciplina "+ disciplina.getNome() +" já ofereceu '"+ numeroTurmas
				+"' Turmas!");

	}
	private void consultarDisciplinasDeProfessor() {
		System.out.println("=============================================================");
		System.out.println("Consulta de Disciplinas já lecionadas por um professor");
		Professor professor = selectProfessor();
		if (professor == null) {
			System.out.println("Nenhum Professor cadastrado");
			return;
		}
		int numeroDisciplinas = turmaDao.numeroDisciplinasPorProfessor(professor.getId());
		System.out.println("Professor "+ professor.getNome() +" ja lecionou/leciona '"+numeroDisciplinas
				+"' Disciplinas diferentes!");
	}
	private boolean clearAll(){
		System.out.print("Deseja apagar todos os dados salvos?(S/n): ");
		char c = Console.readChar();
		if (c == 's' || c == 'S') {
			profDao.clearAll();
			alunoDao.clearAll();
			disciplinaDao.clearAll();
			turmaDao.clearAll();
			atividadeDao.clearAll();
			notaAtividadeDao.clearAll();
			alunoTurmaDao.clearAll();
			return true;
		}
		return false;
	}
	private void showAdm() {
		
		while (true) {
			//clearScreen();
			System.out.println("=============================================================");
			System.out.println("Bem vindo, Administrador. O que desejas fazer?");
			System.out.println("1 - Cadastrar Aluno");
			System.out.println("2 - Cadastrar Professor");
			System.out.println("3 - Cadastrar Disciplina");
			System.out.println("4 - Cadastrar Turma");
			System.out.println("5 - Sair");
			
			int opcao = Console.readInteger();
			if (opcao == 1) {
				this.addAluno();
			} else if (opcao == 2 ) {
				this.addProfessor();
			} else if (opcao == 3 ) {
				this.addDisciplina();
			} else if (opcao == 4 ) {
				this.addTurma();
			} else if (opcao == 5 ) {
				return;
			} else {
				System.out.println("Opcaoo invalida! Tente novamente");
			}
			Console.readChar();
		}
		
	}
	private void addTurma() {
		
		//clearScreen();
		System.out.println("====================== Nova Turma ===========================");
		
		Disciplina disciplina = selectDisciplina();	
		if (disciplina == null) {
			System.out.println("Desculpe, nao é possível cadastrar uma turma, não há nenhuma Disciplina cadastrada.");
			System.out.println("Cadastre uma Disciplina e tente novamente.");
			return;
		}
		Professor professor = selectProfessor();
		if (professor == null) {
			System.out.println("Desculpe, nao é possível cadastrar uma turma, não há nenhum Professor cadastrado.");
			System.out.println("Cadastre um Professor e tente novamente.");
			return;
		}
		System.out.print("Digite o Ano: ");
		int ano = Console.readInteger();
		
		System.out.print("Digite o periodo: ");
		int periodo = Console.readInteger();
		
		System.out.print("Digite o local: ");
		String local = Console.readString();
		
		System.out.print("Digite o horario: ");
		String horario = Console.readString();
		
		System.out.print("Digite o numero de vagas: ");
		int vagas = Console.readInteger();
			
		int id = TurmaDaoImp.getNextId();
		//clearScreen();
			
		Turma turma = new Turma(id, ano, periodo, local, horario, vagas, disciplina.getId(), professor.getId());
		
		if (this.turmaDao.add(turma)) {
			System.out.println("Turma inserida com sucesso!");
			System.out.println("Deseja inserir alunos na turma?(1-Sim; 2-Nao)");
			int c = Console.readInteger(); 
			if ((c == 1)){
				addAlunosToTurma(turma);
			}
		} else {
			System.out.println("Erro: Disciplina e/ou Professor nao cadastrado!");
		}
		
	}
	private boolean addAlunosToTurma(Turma turma) {
		if (alunoDao.isEmpty()){
			//clearScreen();
			System.out.println("=============================================================");
			System.out.println("Desculpe, nao ha nenhum aluno cadastrado.");
			System.out.println("Solicite ao administrador seu cadastro.");
			System.out.println("Pressione 'Enter' para retornar...");
			Console.readChar();
			return false;
		}
		
		if (alunoDao.isEmpty()){ 
			return false;
		}
		
		//clearScreen();
		System.out.println("=============================================================");	
		System.out.println("Alunos:");
		alunoDao.listar();
		while (true) {
			System.out.print("Digite o ID do aluno para adicionar na turma ('-1' para sair): ");
			int id = Console.readInteger();
			if (alunoDao.hasId(id)){
				Aluno aluno = alunoDao.get(id);
				if (!turmaDao.addAluno(aluno, turma, alunoTurmaDao)){
					System.out.println("ERRO: Aluno ja matriculado na turma!");
				}
			} else if (id < 0) {
				System.out.println("alunos inseridos com sucesso!");
				return true;
			} else {
				System.out.println("ERRO: ID nao existente!");
			}
		}
		 
	}
	private void addDisciplina() {
		
		//clearScreen();
		System.out.println("====================== Nova disciplina ===========================");
		System.out.println("Digite o Nome: ");
		String nome = Console.readString();
		System.out.println("Digite a ementa separando os topicos por ';'(ponto e virgula): ");
		String ementa = Console.readString();
		System.out.println("Digite a carga horaria: ");
		int cargaHoraria = Console.readInteger();
		int id = DisciplinaDaoImp.getNextId();
		
		if (this.disciplinaDao.add(new Disciplina(id, nome, ementa, cargaHoraria))) {
			System.out.println("Disciplina inserida com sucesso!");
		} else {
			System.out.println("Erro: Essa disciplina ja esta cadastrada!");
		}
		
	}
	private Disciplina selectDisciplina() {
		if (disciplinaDao.isEmpty()){ 
			return null;
		}
		//clearScreen();
		System.out.println("=============================================================");
		System.out.println("Disciplinas:");
		disciplinaDao.listar();
		while (true) {
			System.out.println("Digite o ID da Disciplina: ");
			int id = Console.readInteger();
			if (disciplinaDao.hasId(id)){
				return disciplinaDao.get(id);	
			} else {
				System.out.println("ID nao existente! Tente novamente");
			}
			Console.readChar();
		}
	}
	private Disciplina selectDisciplina(Aluno aluno) {
		List<Disciplina> disciplinas = turmaDao.disciplinasByList(aluno.getTurmas(turmaDao, alunoTurmaDao), disciplinaDao);
		if (disciplinas.isEmpty()){ 
			return null;
		}
		//clearScreen();
		System.out.println("=============================================================");
		System.out.println("Disciplinas:");
		System.out.println("--------------------");
		for (Disciplina disciplina : disciplinas) {
			System.out.println("-> "+ disciplina.toStringSemEmenta());
		}
		System.out.println("--------------------");
		while (true) {
			System.out.println("Digite o ID da Disciplina: ");
			int id = Console.readInteger();
			if (disciplinas.contains(disciplinaDao.get(id))){
				return disciplinaDao.get(id);	
			} else {
				System.out.println("ID nao existente! Tente novamente");
			}
			Console.readChar();
		}
	}
	private void addProfessor() {
		
		//clearScreen();
		System.out.println("==================== Novo Professor =========================");
		
		System.out.print("Digite o Nome: ");
		String nome = Console.readString();
		System.out.print("Digite o CPF: ");
		String cpf = Console.readString();
		System.out.print("Digite o Departamento: ");
		String dep = Console.readString();
		int id = ProfessorDaoImp.getNextId();
		
		
		if(this.profDao.add(new Professor(id,nome,cpf,dep))){
			System.out.println("Professor inserido com sucesso!");
		} else {
			System.out.println("Erro: CPF de Professor ja cadastrado");
		}
		
	}
	private void addAluno() {
		
		//clearScreen();
		System.out.println("====================== Novo Aluno ===========================");
		
		System.out.print("Digite o Nome: ");
		String nome = Console.readString();
		System.out.print("Digite o CPF: ");
		String cpf = Console.readString();
		int id = AlunoDaoImp.getNextId();
		
		if(this.alunoDao.add(new Aluno(id,nome,cpf))){
			System.out.println("Aluno inserido com sucesso!");
		} else {
			System.out.println("Erro: CPF de Aluno ja cadastrado");
		}
		
	}
	private void showProfessor() {
		if (profDao.isEmpty()){
			//clearScreen();
			System.out.println("=============================================================");
			System.out.println("Desculpe, nao ha nenhum professor cadastrado.");
			System.out.println("Solicite ao administrador seu cadastro.");
			System.out.println("Pressione 'Enter' para retornar...");
			Console.readChar();
			return;
		}
		Professor prof = selectProfessor();
		
		while (true) {
			//clearScreen();
			System.out.println("=============================================================");
			System.out.println("Bem vindo, " + prof.getNome() +". O que desejas fazer?");
			System.out.println("1 - Sair");
			System.out.println("2 - Cadastrar Atividade");
			System.out.println("3 - Logar como outro Professor");
			System.out.println("4 - Lançar/Alterar notas de uma atividade");
			System.out.println("5 - Lançar/Alterar faltas de uma turma");
			int opcao = Console.readInteger();
			//clearScreen();
			if (opcao == 1) {
				return;
			} else if (opcao == 2) {
				this.addAtividade(prof);
			} else if (opcao == 3) {
				prof = selectProfessor();
				System.out.println("Professor alterado com sucesso!");
			} else if (opcao == 4) {
				lancarNotasAtividade(prof);
			} else if (opcao == 5) {
				lancarFaltas(prof);
			} else {
				System.out.println("Opcao invalida! Tente novamente");
			}
			Console.readChar();
		}
		
	}
	private boolean lancarFaltas(Professor prof) {
		Turma turma = selectTurma(prof);
		if (turma == null) {
			System.out.println(prof.getNome()+", você nao tem nenhuma turma cadastrada.");
			System.out.println("Solicite o cadastro ao administrador e tente novamente");
			return false;
		}
		Aluno aluno;
		//clearScreen();
		System.out.println("=============================================================");
		System.out.println(prof.getNome()+", lance as faltas de seus alunos:");
		for (AlunoTurma reg : alunoTurmaDao.getByTurma(turma.getId())) {
			aluno = alunoDao.get(reg.getAlunoId());
			System.out.print("-> '"+aluno.getNome()+"' tem "+reg.getFaltas()+" faltas. Alterar para: ");
			int faltas = Console.readInteger();
			reg.setFaltas(faltas);
		}
		System.out.println("Faltas alteradas!");
		return true;
	}
	private boolean lancarNotasAtividade(Professor prof) {
		Turma turma = selectTurma(prof);
		if (turma == null){
			System.out.println(prof.getNome()+", você nao tem nenhuma turma cadastrada.");
			System.out.println("Solicite o cadastro ao administrador e tente novamente");
			return false;
		}
		Atividade atividade = selectAtividade(turma);
		if (atividade == null){
			System.out.println(prof.getNome()+", você nao tem nenhuma atividade cadastrada.");
			System.out.println("Cadastre a atividade desejada e tente novamente");
			return false;
		}
		lancarNotas(atividade,turma);
		return true;
	}
	private void lancarNotas(Atividade atividade, Turma turma) {
		Aluno aluno;
		//clearScreen();
		System.out.println("=============================================================");
		System.out.println("Cadastro de notas para '" + atividade.getNome() +"' de valor "+atividade.getValor()+" pontos:");
		for (AlunoTurma registro : alunoTurmaDao.getByTurma(turma.getId())) {
			aluno = alunoDao.get(registro.getAlunoId());
			NotaAtividade regAT = registro.getRegistroAtividade(atividade, notaAtividadeDao);
			
			System.out.print("-> Nota atual de '"+aluno.getNome()+"': "+regAT.getNota()+". Alterar para: ");
			float nota = Console.readFloat();
			regAT.setNota(nota);
		}
		System.out.println("Notas lançadas!");
	}
	private Turma selectTurma(Professor prof) {
		if (turmaDao.getByProfessor(prof).isEmpty()){ 
			return null;
		}
		//clearScreen();
		System.out.println("=============================================================");
		System.out.println("Turmas de " + prof.getNome() +  ":");
		turmaDao.listarPorProfessor(prof);
		while (true) {
			System.out.print("Digite o ID da turma: ");
			int id = Console.readInteger();
			if (turmaDao.hasId(id)){
				return turmaDao.get(id);	
			} else {
				System.out.println("ID nao existente! Tente novamente");
			}
			Console.readChar();
		}
	}
	private Atividade selectAtividade(Turma turma) {
		if (atividadeDao.getByTurma(turma).isEmpty()){ 
			System.out.println("Essa turma nao contem atividades");
			return null;
		}
		//clearScreen();
		System.out.println("=============================================================");
		System.out.println("Atividades:");
		atividadeDao.listarPorTurma(turma);
		while (true) {
			System.out.print("Digite o ID da Atividade: ");
			int id = Console.readInteger();
			if (atividadeDao.hasId(id)){
				return atividadeDao.get(id);	
			} else {
				System.out.println("ID nao existente! Tente novamente");
			}
			Console.readChar();
		}
	}
	private Professor selectProfessor() {
		if (profDao.isEmpty()){ 
			return null;
		}
		//clearScreen();
		System.out.println("=============================================================");
		System.out.println("Professores:");
		profDao.listar();
		while (true) {
			System.out.print("Digite o ID do professor: ");
			int id = Console.readInteger();
			if (profDao.hasId(id)){
				return profDao.get(id);	
			} else {
				System.out.println("ID nao existente! Tente novamente");
			}
			Console.readChar();
		}
	}
	private void addAtividade(Professor prof) {
		//clearScreen();
		System.out.println("====================== Nova Atividade =======================");
		if (turmaDao.getByProfessor(prof).isEmpty()) {
			System.out.println(prof.getNome()+", você nao tem nenhuma turma cadastrada.");
			System.out.println("Solicite o cadastro ao administrador e tente novamente");
			return;
		}
		System.out.println("Turmas Cadastradas:");
		turmaDao.listarPorProfessor(prof);
		System.out.print("Digite o codigo da Turma: ");
		int turmaId = Console.readInteger();
		
		System.out.print("Digite o Nome: ");
		String nome = Console.readString();
		
		System.out.print("Digite o Tipo: ");
		String tipo = Console.readString();
		
		System.out.println("Digite a Data: ");
		System.out.print("\tDia: ");
		int dia = Console.readInteger();
		System.out.print("\tMes: ");
		int mes = Console.readInteger();
		System.out.print("\tAno: ");
		int ano = Console.readInteger();	
		
		System.out.print("Digite o Valor: ");
		float valor = Console.readFloat();
		
		int id = AtividadeDaoImp.getNextId();
		
		if(this.atividadeDao.add(new Atividade(id,nome,tipo,new GregorianCalendar(ano,mes,dia),valor,turmaId),
				notaAtividadeDao,alunoTurmaDao,turmaDao)){
			
			System.out.println("Atividade inserida com sucesso!");
		} else {
			System.out.println("Erro: Atividade ja cadastrada id = "+id);	
		}
		
	}
	private Aluno selectAluno() {
		if (alunoDao.isEmpty()){ 
			return null;
		}
		
		System.out.println("=============================================================");	
		System.out.println("Alunos:");
		alunoDao.listar();
		
		while (true) {
			System.out.print("Digite o ID do aluno: ");
			int id = Console.readInteger();
			if (alunoDao.hasId(id)){
				return alunoDao.get(id);
			} else {
				System.out.println("ID nao existente! Tente novamente");
			}
			Console.readChar();
		}
	}
	
	/*private void clearScreen(){
		for (int i = 0; i < 50; i++) {
			System.out.println();
		}
	}*/
}	
